# node net/irc.py

import asyncore
import socket
from tools import parser
from tools import config
import string
import time
import logging
import traceback

BUF=2048

logging.basicConfig(level = logging.DEBUG, format = "%(created)-15s %(msecs)d %(levelname)8s %(thread)d %(name)s %(message)s")
log = logging.getLogger (__name__)

class Conn (asyncore.dispatcher) :
	"""Extended asyncore.dispatcher class."""
	def __init__ (self,plugin_and_rb) :
		"""Initial stuff for the IRC connection"""
		asyncore.dispatcher.__init__ (self)
		self.debug = config.getDebug ()
		if self.debug :
			log.debug ("__init__")
		self.port = config.getIRCPort ()
		self.nick = config.getNodeID ()
		self.addr = config.getIRCServer ()
		self.data_out = ""
		self.new_msg = True
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.pl_and_rb = plugin_and_rb
		self.ready_to_send = False
		self.connect ((self.addr, self.port))
		
	def handle_connect (self) :
		"""Sends the NICK,USER messages and joins to #nodeid channel"""
		if self.debug :
			log.debug ("handle_connect")
		self.send ("NICK %s\r\n" % self.nick)
		self.send ("USER %s %s bla : %s\r\n" % (self.nick, self.addr, \
		self.nick))
		self.send ("JOIN #%s\r\n" % self.nick)
	
	def writable (self) :
		"""Return true, if we have something to send."""
		return self.ready_to_send

	def readable (self) :
		"""We always want to read."""
		return True
	
	def handle_read (self) :
		if self.debug :
			log.debug ("handle_read")
		data_in = self.recv (BUF)
		if self.debug :
			log.debug ("after recv")
		if data_in:
			if self.debug :
				log.debug ("got data")
			msgs = list(string.split(data_in, "\r\n"))
			for msg in msgs :
				m = tuple (string.split (msg, " "))
				if len(m) > 1 and len(m[0]) > 0 :
					if m[0] == "PING" :
						self.send ("PONG %s\r\n" + m[1])
					elif len(m) > 3 and m[1] == "PRIVMSG" :
						mm = m[3][1:]
						mm += " " + string.join (m[4:], " ")
						parser.parsemsg (mm, self, self.pl_and_rb)

		else :
			if self.debug :
				log.debug ("no data")
	
	def handle_write (self) :
		if self.debug :
			log.debug ("handle_write")
		if self.data_out :
			if self.new_msg :
				self.data_out = "PRIVMSG #%s" % self.nick + " :" + self.data_out
				self.new_msg = False
			sent = self.send (self.data_out)
			if self.debug :
				log.debug ("data sent")
			self.data_out = self.data_out[sent:]
		else :
			if self.debug :
				log.debug ("nothing to send")
		if len (self.data_out) == 0 :
			self.ready_to_send = False
			self.new_msg = True
	
	def handle_error (self) :
		if self.debug :
			log.debug ("handle_error")
			traceback.print_exc ()
		self.close ()
		time.sleep (30)
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.connect ((self.addr, self.port))
	
	def handle_close (self) :
		if self.debug :
			log.debug ("handle_close")
		self.close ()
		time.sleep (30)
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.connect ((self.addr, self.port))
	
	def send_msg (self, data) :
		""" """
		self.data_out += data
		self.ready_to_send = True

